﻿/****************************************************************************
 * ClientConnectionHandler
 * Handles the client connection and I/O
 * 
 * 20110608 - md - Exc handling 
 * *************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
using System.Collections;
using System.Xml;


namespace KinectMsSdkServer
{
    class ClientConnectionHandler
    {
        private TcpClient clientSocket;
        private StreamReader inputStream;
        private StreamWriter outputStream;
        private NetworkStream networkStream;
        private bool bailOut;
        private KinectHandler kinectHandle;
        private HashSet<String> subscribtions = new HashSet<String>();

        public event EventHandler<EventArgs> DisconnectedEvent;

        public String getRemoteAddress()
        {
            IPEndPoint e = (IPEndPoint)clientSocket.Client.RemoteEndPoint;
            return e.Address + ":" + e.Port;
        }

        public String[] getSubscribtions()
        {
            return subscribtions.ToArray();
        }
        public ClientConnectionHandler(TcpClient socket, KinectHandler kinect, MainServerThread manager)
        {
            clientSocket = socket;
            networkStream = clientSocket.GetStream();
            inputStream = new StreamReader(clientSocket.GetStream());
            outputStream = new StreamWriter(clientSocket.GetStream());
            outputStream.AutoFlush = true;
            kinectHandle = kinect;
            new Thread(handleIO).Start();
        }

        public void distribute(String cmd)
        {
            try
            {
                outputStream.WriteLine(cmd);
            }
            catch (Exception)
            {
                Console.WriteLine("Could not send '" + cmd + "'");
            }
        }
        public void handleIO()
        {
            bailOut = false;
            try
            {
                while (clientSocket.Connected && !bailOut)
                {

                    if (networkStream.DataAvailable && !bailOut)
                    {
                        try
                        {
                            while (!inputStream.EndOfStream)
                            {
                            String s = inputStream.ReadLine();
                            Console.WriteLine("Received: {0}", s);
                            outputStream.WriteLine(handleCommand(s));
                             }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Broken read: " + e.Message);
                        }
                    }

                }
            }
            finally
            {
                // Unsubscribe all events
                DisconnectedEvent(this, null);
                Console.WriteLine("Subscribtions cancelled");
            }

            Console.WriteLine("Client disconnected");
            clientSocket.Close();
        }

        private String handleCommand(String s)
        {
            String initSpeech = "INIT SPEECH RECOGNITION: ";
            if (s.Equals("START SKELETON TRACKING"))
            {
                kinectHandle.startSkeletonTracking(this);
                
                return "OK";
            }
            else if (s.StartsWith(initSpeech))
            {
                String words = s.Substring(initSpeech.Length);
                string[] sep = { ", " };
                SpeechRecognition.setup(words.Split(sep, 100, System.StringSplitOptions.None), outputStream);
                return "OK";
            }
            else if (s.Equals("RESUME SPEECH RECOGNITION"))
            {
                SpeechRecognition.startRecog();
                return "OK";
            }
            else if (s.Equals("STOP SPEECH RECOGNITION"))
            {
                SpeechRecognition.stop();
                return "OK";
            }
            return "ERROR";
        }

       
       public void sendSkeleton(String doc)
        {
            
            try
            {
                outputStream.Write(doc);
        
            }
            catch (Exception e11)
            {
                Console.WriteLine("Exception: " + e11);
            }
        }
    }
}
